package org.vaadinpa.gui;

import java.util.Date;
import java.util.List;

import org.vaadin.kim.countdownclock.CountdownClock;
import org.vaadinpa.data.Fleet;
import org.vaadinpa.data.Fleet.FleetOrder;
import org.vaadinpa.data.NewsItem;
import org.vaadinpa.data.Planet;
import org.vaadinpa.data.Resource;
import org.vaadinpa.gui.util.NotificationUtil;
import org.vaadinpa.logic.Command;
import org.vaadinpa.logic.CommandHandler;
import org.vaadinpa.logic.Ticker;
import org.vaadinpa.logic.commands.FleetMoveCommand;

import com.vaadin.ui.Alignment;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;

public class Header extends GridLayout {

	private static final long serialVersionUID = 3145091029453337303L;

	private final Label metalLabel = new Label("", Label.CONTENT_XHTML);
	private final Label crystalLabel = new Label("", Label.CONTENT_XHTML);
	private final Label goldLabel = new Label("", Label.CONTENT_XHTML);

	private final Label playerLabel = new Label("", Label.CONTENT_XHTML);
	private final Label scoreLabel = new Label();
	private final Label tickLabel = new Label("", Label.CONTENT_XHTML);
	private final CountdownClock clock = new CountdownClock();

	private final Label incomingAttackersLabel = new Label("Incoming attackers!");
	private final Label incomingDefendersLabel = new Label("Incoming defenders!");
	private final Label unreadNewsLabel = new Label("Unread news");

	private static final String placeholder = "_";
	private static final String resourceTemplate = "" + placeholder + ": " + placeholder + "<br>" + placeholder
			+ " asteroids";

	private final Planet planet;

	private int lastNotifiedTick;

	public Header() {
		super(7, 2);
		setColumnExpandRatio(1, 1);
		setColumnExpandRatio(5, 1);

		planet = VaadinPA.getPlanet();

		Label logo = new Label("ICanHasPA");
		logo.addStyleName("logo");
		logo.setSizeUndefined();
		addComponent(logo);

		HorizontalLayout hl = new HorizontalLayout();
		hl.setWidth("300px");
		tickLabel.setSizeUndefined();
		clock.setVisible(false);
		clock.setFormat(" Ticks start in: %h h, %m m, %s s.");
		clock.setDate(new Date());
		clock.setSizeUndefined();
		hl.addComponent(tickLabel);
		hl.addComponent(clock);
		addComponent(hl, 0, 1);

		addComponent(metalLabel, 2, 0);
		addComponent(crystalLabel, 3, 0);
		addComponent(goldLabel, 4, 0);

		playerLabel.setValue("<b>" + planet.ruler + "</b>, ruler of <b>" + planet.name + "</b><br/>" + "Coordinates: "
				+ VaadinPA.getPlanet().coords.x + ":" + VaadinPA.getPlanet().coords.y);
		playerLabel.setSizeUndefined();
		addComponent(playerLabel, 6, 0);

		scoreLabel.setSizeUndefined();
		addComponent(scoreLabel, 6, 1);

		addComponent(incomingAttackersLabel, 2, 1);
		incomingAttackersLabel.addStyleName("attackers");
		incomingAttackersLabel.setVisible(false);

		addComponent(unreadNewsLabel, 3, 1);
		unreadNewsLabel.addStyleName("news");
		unreadNewsLabel.setVisible(false);

		addComponent(incomingDefendersLabel, 4, 1);
		incomingDefendersLabel.addStyleName("defenders");
		incomingDefendersLabel.setVisible(false);

		setComponentAlignment(logo, Alignment.MIDDLE_LEFT);

		setMargin(true);
		setWidth("100%");
		setHeight("100px");
		addStyleName("header");

		reload();
	}

	private void updateResourceLabel(Label l, Resource resource) {
		String text = new String(resourceTemplate);
		text = text.replaceFirst(placeholder, resource.toString());
		text = text.replaceFirst(placeholder, planet.getFunds(resource) + "");
		text = text.replaceFirst(placeholder, planet.roids.get(resource).toString());
		l.setValue(text);
		l.setStyleName("resource");
		l.setSizeUndefined();
		l.setWidth(150, UNITS_PIXELS);
	}

	public List<Class<? extends Command>> getCommandTypes() {
		return null;
	}

	private void updateIncoming() {
		incomingAttackersLabel.setVisible(false);
		incomingDefendersLabel.setVisible(false);

		for (FleetMoveCommand c : CommandHandler.getAllFleetMoveCommands()) {
			if (c.planet.equals(VaadinPA.getPlanet())) {
				// ignore own fleets
				continue;
			}

			if (c.destination.equals(VaadinPA.getPlanet().coords) && c.fleet.location == null) {
				Fleet f = c.fleet;

				if (f.currentOrder == FleetOrder.ATTACK) {
					incomingAttackersLabel.setVisible(true);
				} else {
					incomingDefendersLabel.setVisible(true);
				}
			}
		}

		unreadNewsLabel.setVisible(false);
		for (NewsItem n : VaadinPA.getPlanet().news) {

			if (!n.read) {
				unreadNewsLabel.setVisible(true);
			}
			// if first is read, then all are
			break;
		}
	}

	void reload() {
		clock.setVisible(false);
		if (Ticker.areTicksRunning()) {
			tickLabel
					.setValue("Ticks are <span style=\"color: lightgreen;font-weight: bold;\">running</span>, current tick: "
							+ Ticker.currentTick);
			clock.setDate(new Date());
		} else {
			Date tickStart = Ticker.getSecondsUntilTickStart();
			if (tickStart != null) {
				clock.setDate(tickStart);
				clock.setVisible(true);
				tickLabel.setValue("Ticks are <span style=\"color:red;\">suspended</span>.");
			} else {
				tickLabel.setValue("Ticks are <span style=\"color:red;\">stopped</span>.");
			}
		}
		scoreLabel.setValue("Score: " + VaadinPA.getPlanet().score);
		updateResourceLabel(metalLabel, Resource.METAL);
		updateResourceLabel(crystalLabel, Resource.CRYSTAL);
		updateResourceLabel(goldLabel, Resource.GOLD);

		updateIncoming();

		if (getWindow() != null && lastNotifiedTick < Ticker.currentTick) {
			NotificationUtil.notify("Tick occured", "");
			lastNotifiedTick = Ticker.currentTick;
		}
	}

}
